using Microsoft.EntityFrameworkCore;
using DaoHang.Data;
using DaoHang.Models;
using BCrypt.Net;

namespace DaoHang.Services
{
    /// <summary>
    /// 用户服务实现类，处理用户认证相关的业务逻辑
    /// </summary>
    public class UserService : IUserService
    {
        private readonly ApplicationDbContext context;
        private readonly ILogger<UserService> logger;

        /// <summary>
        /// 构造函数，注入依赖服务
        /// </summary>
        /// <param name="context">数据库上下文</param>
        /// <param name="logger">日志记录器</param>
        public UserService(ApplicationDbContext context, ILogger<UserService> logger)
        {
            this.context = context;
            this.logger = logger;
        }

        /// <summary>
        /// 用户登录验证
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns>登录是否成功</returns>
        public async Task<bool> ValidateUserAsync(string username, string password)
        {
            try
            {
                if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
                    return false;

                var user = await GetUserByUsernameAsync(username);
                if (user == null)
                    return false;

                return VerifyPassword(password, user.PasswordHash);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "验证用户登录时发生错误: {Username}", username);
                return false;
            }
        }

        /// <summary>
        /// 根据用户名获取用户信息
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns>用户信息</returns>
        public async Task<User?> GetUserByUsernameAsync(string username)
        {
            try
            {
                return await context.Users
                    .FirstOrDefaultAsync(u => u.Username == username);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "根据用户名获取用户信息时发生错误: {Username}", username);
                return null;
            }
        }

        /// <summary>
        /// 创建默认管理员账户
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="email">邮箱（可选）</param>
        /// <returns>创建的用户</returns>
        public async Task<User> CreateDefaultAdminAsync(string username, string password, string? email = null)
        {
            try
            {
                // 检查用户名是否已存在
                var existingUser = await GetUserByUsernameAsync(username);
                if (existingUser != null)
                {
                    throw new InvalidOperationException($"用户名 '{username}' 已存在");
                }

                var user = new User
                {
                    Username = username,
                    PasswordHash = HashPassword(password),
                    Email = email,
                    IsAdmin = true,
                    CreateTime = DateTime.Now
                };

                context.Users.Add(user);
                await context.SaveChangesAsync();

                logger.LogInformation("成功创建默认管理员账户: {Username}", username);
                return user;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "创建默认管理员账户时发生错误: {Username}", username);
                throw;
            }
        }

        /// <summary>
        /// 创建管理员账户（简化版本）
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns>创建的用户</returns>
        public async Task<User> CreateAdminUserAsync(string username, string password)
        {
            return await CreateDefaultAdminAsync(username, password);
        }

        /// <summary>
        /// 检查是否存在管理员账户
        /// </summary>
        /// <returns>是否存在管理员</returns>
        public async Task<bool> HasAdminUserAsync()
        {
            try
            {
                return await context.Users.AnyAsync(u => u.IsAdmin);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "检查管理员账户是否存在时发生错误");
                return false;
            }
        }

        /// <summary>
        /// 获取所有用户列表（调试用）
        /// </summary>
        /// <returns>用户列表</returns>
        public async Task<IEnumerable<User>> GetAllUsersAsync()
        {
            try
            {
                return await context.Users.ToListAsync();
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取用户列表时发生错误");
                return Enumerable.Empty<User>();
            }
        }

        /// <summary>
        /// 密码哈希
        /// </summary>
        /// <param name="password">明文密码</param>
        /// <returns>哈希后的密码</returns>
        public string HashPassword(string password)
        {
            return BCrypt.Net.BCrypt.HashPassword(password, BCrypt.Net.BCrypt.GenerateSalt(12));
        }

        /// <summary>
        /// 验证密码
        /// </summary>
        /// <param name="password">明文密码</param>
        /// <param name="hash">哈希密码</param>
        /// <returns>密码是否正确</returns>
        public bool VerifyPassword(string password, string hash)
        {
            try
            {
                return BCrypt.Net.BCrypt.Verify(password, hash);
            }
            catch (Exception ex)
            {
                logger.LogWarning(ex, "验证密码时发生错误");
                return false;
            }
        }

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="oldPassword">旧密码</param>
        /// <param name="newPassword">新密码</param>
        /// <returns>是否修改成功</returns>
        public async Task<bool> ChangePasswordAsync(string username, string oldPassword, string newPassword)
        {
            try
            {
                var user = await GetUserByUsernameAsync(username);
                if (user == null)
                {
                    logger.LogWarning("尝试修改不存在用户的密码: {Username}", username);
                    return false;
                }

                // 验证旧密码
                if (!VerifyPassword(oldPassword, user.PasswordHash))
                {
                    logger.LogWarning("用户 {Username} 提供的旧密码不正确", username);
                    return false;
                }

                // 更新密码
                user.PasswordHash = HashPassword(newPassword);
                await context.SaveChangesAsync();

                logger.LogInformation("用户 {Username} 成功修改密码", username);
                return true;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "修改用户密码时发生错误: {Username}", username);
                return false;
            }
        }

        /// <summary>
        /// 管理员重置用户密码
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="newPassword">新密码</param>
        /// <returns>是否重置成功</returns>
        public async Task<bool> ResetPasswordAsync(string username, string newPassword)
        {
            try
            {
                var user = await GetUserByUsernameAsync(username);
                if (user == null)
                {
                    logger.LogWarning("尝试重置不存在用户的密码: {Username}", username);
                    return false;
                }

                // 直接重置密码
                user.PasswordHash = HashPassword(newPassword);
                await context.SaveChangesAsync();

                logger.LogInformation("管理员重置用户 {Username} 的密码", username);
                return true;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "重置用户密码时发生错误: {Username}", username);
                return false;
            }
        }

        /// <summary>
        /// 获取管理员用户
        /// </summary>
        /// <returns>管理员用户信息</returns>
        public async Task<User?> GetAdminUserAsync()
        {
            try
            {
                return await context.Users
                    .FirstOrDefaultAsync(u => u.IsAdmin);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取管理员用户时发生错误");
                return null;
            }
        }

        /// <summary>
        /// 更新管理员用户信息
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns>是否更新成功</returns>
        public async Task<bool> UpdateAdminUserAsync(string username, string password)
        {
            try
            {
                var admin = await GetAdminUserAsync();
                if (admin == null)
                {
                    logger.LogWarning("尝试更新不存在的管理员用户");
                    return false;
                }

                // 更新用户名和密码
                admin.Username = username;
                if (!string.IsNullOrEmpty(password))
                {
                    admin.PasswordHash = HashPassword(password);
                }

                await context.SaveChangesAsync();
                logger.LogInformation("成功更新管理员用户信息: {Username}", username);
                return true;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "更新管理员用户信息时发生错误: {Username}", username);
                return false;
            }
        }
    }
} 